package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.bean.BeanUtils;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.dto.ElderFamilyDto;
import com.zzyl.nursing.mapper.*;
import com.zzyl.nursing.util.CodeGenerator;
import com.zzyl.nursing.vo.CheckInConfigVo;
import com.zzyl.nursing.vo.CheckInDetailVo;
import com.zzyl.nursing.vo.CheckInElderVo;
import com.zzyl.nursing.vo.ElderFamilyVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;

/**
 * 入住Service业务层处理
 *
 * @author ruoyi
 * @date 2025-07-25
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService {
    @Autowired
    private CheckInMapper checkInMapper;
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private CheckInConfigMapper checkInConfigMapper;
    @Autowired
    private ContractMapper contractMapper;
    @Autowired
    private BedMapper bedMapper;

    /**
     * 查询入住
     *
     * @param id 入住主键
     * @return 入住
     */
    @Override
    public CheckIn selectCheckInById(Long id) {
        return getById(id);
    }

    /**
     * 查询入住列表
     *
     * @param checkIn 入住
     * @return 入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn) {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn) {
        return save(checkIn) ? 1 : 0;
    }

    /**
     * 修改入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn) {
        return updateById(checkIn) ? 1 : 0;
    }

    /**
     * 批量删除入住
     *
     * @param ids 需要删除的入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除入住信息
     *
     * @param id 入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 入住申请
     *
     * @param dto 请求的实体类
     */
    @Transactional
    @Override
    public void apply(CheckInApplyDto dto) {
        try {
            //1.校验验老人是否已入住
            LambdaQueryWrapper<Elder> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Elder::getIdCardNo, dto.getCheckInElderDto().getIdCardNo());
            queryWrapper.eq(Elder::getStatus, 1);
            Elder elder = elderMapper.selectOne(queryWrapper);
            if (ObjectUtils.isNotEmpty(elder)) {
                throw new BaseException("老人已入住");
            }
            //2.更新床位状态为已入住
            Bed bed = bedMapper.selectById(dto.getCheckInConfigDto().getBedId());
            bed.setBedStatus(1);
            bedMapper.updateBed(bed);
            //3.新增或者更新老人
            elder = inserElder(dto, bed);
            //4.新增签约办理
            insertContract(elder, dto);
            //5.新增入住信息
            CheckIn checkIn = addCheckIn(elder, dto, bed);
            //6.新增入住配置
            addCheckInConfig(dto,checkIn);
        } catch (BaseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询入住详情
     *
     * @param id
     * @return
     */
    @Override
    public CheckInDetailVo detail(Long id) {
        //返回的数据有：老人响应信息，家属响应信息，入住配置响应信息，签约办理响应信息
        //1.通过入住id查询入住表和入住配置表的信息、并插入到入住配置响应信息实体类中
        CheckIn checkIn = checkInMapper.selectCheckInById(id);
        if (ObjectUtils.isEmpty(checkIn)) {
            log.error("入住id不存在");
            throw new BaseException("入住id不存在");
        }
        CheckInConfig checkInConfig = checkInConfigMapper.selectCheckInConfigByCheckInId(id);
        CheckInConfigVo checkInConfigVo = new CheckInConfigVo();
        BeanUtils.copyProperties(checkInConfig, checkInConfigVo);
        checkInConfigVo.setCreateBy(checkIn.getCreateBy());
        checkInConfigVo.setCreateTime(checkIn.getCreateTime());
        checkInConfigVo.setUpdateTime(checkIn.getUpdateTime());
        checkInConfigVo.setSortOrder(checkIn.getSortOrder());
        checkInConfigVo.setStartDate(checkIn.getStartDate());
        checkInConfigVo.setEndDate(checkIn.getEndDate());
        checkInConfigVo.setBedNumber(checkIn.getBedNumber());


        //2.通过id查询家属信息并赋值到家属响应信息的实体类中
        String remark = checkInMapper.selectRemarkById(id);
        Object parse = JSON.parse(remark);
        List<ElderFamilyVo> list = JSON.parseArray(parse.toString(), ElderFamilyVo.class);


        //3.通过id查询老人信息并赋值到老人响应信息的实体类中
        Elder elder = elderMapper.selectById(checkIn.getElderId());
        //3.1 通过拿到老人的出生日期计算年龄，并赋值给老人响应信息实体类中
        String birthday = elder.getBirthday();
        String substring = birthday.substring(0, 4);
        // 计算年龄并设置
        int age = 0;
        if (StringUtils.isNotEmpty(birthday)) {
            age = LocalDateTime.now().getYear() - Integer.parseInt(substring);
        }
        CheckInElderVo checkInElderVo = new CheckInElderVo();
        checkInElderVo.setAge(age);
        BeanUtils.copyProperties(elder, checkInElderVo);


        //4.签约办理响应信息
        Contract contract = contractMapper.selectByElderId(checkIn.getElderId());


        //5.赋值给入住详情响应信息
        CheckInDetailVo checkInDetailVo = new CheckInDetailVo();
        checkInDetailVo.setContract(contract);
        checkInDetailVo.setCheckInElderVo(checkInElderVo);
        checkInDetailVo.setElderFamilyVoList(list);
        checkInDetailVo.setCheckInConfigVo(checkInConfigVo);

        return checkInDetailVo;
    }

    private void addCheckInConfig(CheckInApplyDto dto, CheckIn checkIn) {
        CheckInConfig checkInConfig = new CheckInConfig();
        BeanUtils.copyBeanProp(checkInConfig, dto.getCheckInConfigDto());
        BeanUtils.copyProperties(dto.getCheckInConfigDto(), checkInConfig);
        checkInConfig.setCheckInId(checkIn.getId());
        checkInConfigMapper.insert(checkInConfig);
    }


    private CheckIn addCheckIn(Elder elder, CheckInApplyDto dto,Bed bed) {
        CheckIn checkIn = new CheckIn();
        BeanUtils.copyBeanProp(checkIn, dto.getCheckInConfigDto());
        checkIn.setElderId(elder.getId());
        checkIn.setElderName(elder.getName());
        checkIn.setIdCardNo(elder.getIdCardNo());
        checkIn.setStatus(0);
        checkIn.setBedNumber(bed.getBedNumber());

        //在入住表里添加家属的信息、并转为字符串格式
        List<ElderFamilyDto> familyList = dto.getElderFamilyDtoList();
        String string = JSON.toJSONString(familyList);
        checkIn.setRemark(string);

        checkInMapper.insert(checkIn);
        return checkIn;
    }

    private Contract insertContract(Elder elder, CheckInApplyDto dto) {
        Contract contract = new Contract();
        BeanUtils.copyBeanProp(contract, dto.getCheckInContractDto());
        contract.setElderId(elder.getId());
        contract.setElderName(elder.getName());
        //生成合同的编号
        contract.setContractNumber("HT" + CodeGenerator.generateContractNumber());
        //开始时间和结束时间
        contract.setStartDate(dto.getCheckInConfigDto().getStartDate());
        contract.setEndDate(dto.getCheckInConfigDto().getEndDate());
        //状态的判断 如果当前的系统时间在开始时间之后，则状态为1，否则为0
        contract.setStatus(LocalDateTime.now().isAfter(dto.getCheckInConfigDto().getStartDate()) ? 1 : 0);
        contractMapper.insert(contract);

        return contract;
    }

    private Elder inserElder(CheckInApplyDto dto, Bed bed) {
        Elder elder = new Elder();
        BeanUtils.copyBeanProp(elder, dto.getCheckInElderDto());
        elder.setStatus(1);
        elder.setBedId(bed.getId());
        elder.setBedNumber(bed.getBedNumber());

        LambdaQueryWrapper<Elder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Elder::getIdCardNo, dto.getCheckInElderDto().getIdCardNo());
        queryWrapper.eq(Elder::getStatus, 0);
        Elder elder1 = elderMapper.selectOne(queryWrapper);
        if (ObjectUtils.isNotEmpty(elder1)) {
            elder.setId(elder1.getId());
            //存在则更新
            elderMapper.updateElder(elder);
        } else {
            //不存在则新增
            elderMapper.insert(elder);
        }
        return elder;
    }

}
